/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

//The recorder object
//does most of the heavy lifting
Recorder = {

    eventList : [
        //"mousemove", // <=== NOISY!!!
        "mouseover",
        "mouseout",
        "mousedown",
        "mouseup",
        "click",
        "dblclick",
        "mousedrag",
        "dragdrop",
        "keydown",
        "keyup",
        "keypress",
        "scroll",
        "load",
        "unload",
        "beforeunload",
        "reload",
        "select",
        "change",
        "blur",
        "focus"
    ],

    RECORDED_EVENTS : [],

    getRelativeXpath : function(current) {
        if(!current.parentNode)
            return "";
        var index = this.getNodeIndex(current);
        var currentPath = '/' + current.nodeName.toLowerCase();
        if (index > 0) {
            currentPath += '[' + (index + 1) + ']';
        }
        return currentPath;
    },

    getNodeIndex : function(current) {
        var childNodes = current && current.parentNode && current.parentNode.childNodes;
        if(!childNodes)
            return -1;
        var total = 0;
        for (var i = 0; i < childNodes.length; i++) {
            var child = childNodes[i];
            if (child.nodeName == current.nodeName) {
                if (child == current) {
                    return total;
                }
                total++;
            }
        }
        return -1;
    },

    validateElementId : function(element){
        return element.id;
    },

    generateXpath : function(element) {
        if(!element)
            return null;
        var xpath = "";
        var e = element;
        while(e){
            if(this.validateElementId(e)){
                xpath = "//" + e.id + xpath;
                break;
            }
            else{
                xpath = this.getRelativeXpath(e) + xpath;
                e = e.parentNode;
            }
        }
        return xpath;
    },

    captureEventProperties : function(evt){

        var namecheck = function(name){
            name = name.toLowerCase();
            if(Array.prototype.indexOf)
                return Recorder.eventList.indexOf(name);
            else{
                for(var i=0;i<Recorder.eventList.length;i++){
                    if(name === Recorder.eventList[i])
                        return i;
                }
                return -1;
            }

        };

        var obj = {};
        for(var name in evt){
           var val = evt[name];
           var typ = typeof val;
           if(val instanceof Array)
               continue;
           if(val instanceof Object || typ == "object")
               continue;
           if(val instanceof Function)
               continue;
           if(namecheck(name) > -1)
               continue;
           obj[name] = val;
        }
        return obj;
    },

    recordEvent : function(name, event){
        if(name == "unload"){
            setTimeout("registerHandlersOnOpener()", 2000);
        }
        var data =
        {
            name: name,
            xpath: this.generateXpath(event.target),
            timestamp: new Date().getTime(),
            event: this.captureEventProperties(event)
        };
        this.RECORDED_EVENTS.push(data);
    },

    registerEventListeners: function(target){
        log("Registering Event Listeners...")
        this.processListeners(target, true);
        log("Event Listeners Registered.")
    },

    unregisterEventListeners: function(target){
        log("Unregistering Event Listeners...")
        this.processListeners(target, false);
        log("Event Listeners Unregistered.")
    },

    processListeners: function(target, doAdd){

        for(var i=0;i < Recorder.eventList.length;i++){
            var evname = Recorder.eventList[i];
            var handlername = "__" + evname;

            if(!Recorder[handlername])
            {
                var builder = function(){
                    var name = evname;
                    return function(ev){
                        Recorder.recordEvent(name, ev);
                    }
                };
                Recorder[handlername] = builder();

            }

            var listener = Recorder[handlername];

            if(doAdd){
                if(target.addEventListener)
                    target.addEventListener(evname, listener, true);
                else if(target.attachEvent)
                    target.attachEvent("on" + evname, listener);
            }
            else{
                if(target.removeEventListener)
                    target.removeEventListener(evname, listener, true);
                else if(target.detachEvent)
                    target.detachEvent("on" + evname, listener);
            }
        }

        if(doAdd && target.setCapture)
            target.setCapture();
        else if(!doAdd && target.releaseCapture)
            target.releaseCapture();
    },

    serializeEvents: function(){
       log(this.RECORDED_EVENTS.length + " Events Recorded")
       return JSON.stringify(this.RECORDED_EVENTS, null, 2);
    },

    clearEvents : function(){
        this.RECORDED_EVENTS = [];
    }
}

function log(msg){
    var element = document.getElementById("log");
    if(element)
        element.value += msg + "\n";
}

function setRecordedText(eventString){
    var element = document.getElementById("RecordedEvents");
    if(element)
        element.value = eventString;
}

function displayEvents(){
    log("Displaying events...");
    setRecordedText(Recorder.serializeEvents());
}

function startRecording(){
    log("Starting...");
    registerHandlersOnOpener();
    setRecordedText(null);
}

function stopRecording(){
    log("Stopping...");
    unregisterHandlersOnOpener();
    setRecordedText(Recorder.serializeEvents());
}

function clearRecording(){
    log("Clearing recorded events...")
    Recorder.clearEvents();
    setRecordedText(null);
}

function registerHandlersOnOpener(){
    if(window.opener){
        Recorder.registerEventListeners(window.opener);
    }
    else{
        Recorder.registerEventListeners(window);
    }
}

function unregisterHandlersOnOpener(){
    if(window.opener){
        Recorder.unregisterEventListeners(window.opener);
    }
    else{
        Recorder.unregisterEventListeners(window);
    }
}

function loadRecorderWindow (){
    var twindow = window.open("RecorderWindow.html", "_blank");
    twindow.opener = window;
}